/*-
 * Copyright (c) 2012 CTPP Team
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the CTPP Team nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      UnicodeUtils.hpp
 *
 * $CTPP$
 */
#ifndef _UNICODE_UTILS_HPP__
#define _UNICODE_UTILS_HPP__ 1

/**
  @file UnicodeUtils.hpp
  @brief Unicode utilities
*/

// Local includes
#include "Types.h"
#include "CharTables.hpp"

#include <stdio.h>

namespace FTSS
{

/**
  @class Unicode UnicodeUtils.hpp <UnicodeUtils.hpp>
  @brief Unicode support
*/
class Unicode
{
public:

	/**
	  @brief Convert wide character to UTF-8
	  @param iUCS - Wide character
	  @param itsUTF8 - iterator or pointer to first octet of UTF-8 buffer. Buffer MUST contain at least 6 octets
	  @param iUCS - Wide character [out]
	  @return Length of character in octets, -1 - otherwise
	*/
	template <typename T> static INT_32 WideToUTF8(UINT_32    iUCS,
	                                               T        & itsUTF8);

	/**
	  @brief Convert UTF-8 character to wide
	  @param itsIUTF8 - iterator or pointer to first octet of UTF-8 character
	  @param iBufferLength - size of buffer
	  @param iUCS - Wide character [out]
	  @return Length of character in octets, -1 - otherwise
	*/
	template <typename T> static INT_32 UTF8ToWide(T             & itsIUTF8,
	                                               const UINT_64   iBufferLength,
	                                               UINT_32       & iUCS);

	/**
	  @brief Convert UTF-8 character to wide
	  @param itsIUTF8 - iterator or pointer to first octet of UTF-8 character
	  @param itsIUTF8End - iterator or pointer to last octet in buffer
	  @param iUCS - Wide character [out]
	  @return Length of character in octets, -1 - otherwise
	*/
	template <typename T> static INT_32 UTF8ToWide(T             & itsIUTF8,
	                                               const T       & itsIUTF8End,
	                                               UINT_32       & iUCS);

	/**
	  @brief Get length of UTF-8 character
	  @param itsIUTF8 - iterator or pointer to first octet of UTF-8 character
	  @param iBufferLength - size of buffer
	  @return Length of string in UTF-8 characters, -1 - otherwise
	*/
	template <typename T> static INT_32 UTF8Length(T              itsIUTF8,
	                                               const UINT_64  iBufferLength);

	/**
	  @brief Get length of UTF-8 character
	  @param itsIUTF8 - iterator or pointer to first octet of UTF-8 character
	  @param itsIUTF8End - iterator or pointer to last octet in buffer
	  @return Length of string in UTF-8 characters, -1 - otherwise
	*/
	template <typename T> static INT_32 UTF8Length(T          itsIUTF8,
	                                               const T  & itsIUTF8End);

	/**
	  @brief Compare two strings
	*/
	template <typename T> static INT_32 Compare(T        itsFirst,
	                                            UINT_64  iFirstLength,
	                                            T        itsSecond,
	                                            UINT_64  iSecondLength);

	/**
	  @brief Compare two strings
	*/
	template <typename T> static INT_32 Compare(const T  itsFirst,
	                                            const T  itsFirstEnd,
	                                            const T  itsSecond,
	                                            const T  itsSecondEnd);

	/**
	  @brief Compare two strings, ignore case
	*/
	template <typename T> static INT_32 CompareIgnoreCase(const T  itsFirst,
	                                                      UINT_64  iFirstLength,
	                                                      const T  itsSecond,
	                                                      UINT_64  iSecondLength);

	/**
	  @brief Compare two strings, ignore case
	*/
	template <typename T> static INT_32 CompareIgnoreCase(const T  itsFirst,
	                                                      const T  itsFirstEnd,
	                                                      const T  itsSecond,
	                                                      const T  itsSecondEnd);

	/**
	  @brief  Make a UTF8 string lowercase
	*/
	static INT_32 Lowercase(CCHAR_P    szSrc,
	                        UINT_64    iSrcLen,
	                        CHAR_P const szDst,
				const UINT_64 iDstMaxLen,
	                        UINT_64  & iDstLen);

	/**
	  @brief  Make a UTF8 string uppercase
	*/
	static INT_32 Uppercase(CCHAR_P    szSrc,
	                        UINT_64    iSrcLen,
	                        CHAR_P const szDst,
				const UINT_64 iDstMaxLen,
	                        UINT_64  & iDstLen);
private:

};

#include "UnicodeUtils.tcc"

} // namespace MAIL
#endif // _SYSTEM_VARS_HPP__
// End.
